package com.jonah.demo.hbase.thrift.common;


import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

/**
 * 功能描述：完成与日期相关的各种操作
 *
 * <p>包括将日期格式化、从字符串中解析出对应的日期、对日期的加减操作等
 *
 * @author maluming 2011-4-14
 * @see
 * @since 1.0
 */
public class DateUtils {
    public static final String FULL_TIME_FORMATE = "HH:mm:ss";
    public static final String FULL_DATE_FORMATE = "yyyy-MM-dd";
    public static final String FULL_DATE_TIME_FORMATE = FULL_DATE_FORMATE + " " + FULL_TIME_FORMATE;
    public static final String SIMPLE_DATE_FORMATE = "yyyyMMdd";
    public static final String SIMPLE_DATE_FORMATE_SIMPLE = "yyMMdd";
    public static final String SIMPLE_TIME_FORMATE = "HHmmss";
    public static final String SIMPLE_DATE_TIME_FORMATE = SIMPLE_DATE_FORMATE_SIMPLE + SIMPLE_TIME_FORMATE;
    public static final String SIMPLE_DATE_MONTH_FORMATE = "yyyy-MM";
    private static final Logger LOGGER = LoggerFactory.getLogger(DateUtils.class);

    /**
     * 功能描述：按照给出格式解析出日期
     *
     * @param dateStr String 字符型日期
     * @param format  String 格式
     * @return Date 日期
     */
    public static Date parseDate(String dateStr, String format) {
        Date date = null;
        try {
            DateFormat df_parseDate = new SimpleDateFormat(format);
            String dt = dateStr;
            date = (Date) df_parseDate.parse(dt);
        } catch (Exception e) {
        }
        return date;
    }

    /**
     * 功能描述：格式化日期
     *
     * @param dateStr String 字符型日期：YYYY-MM-DD 格式
     * @return Date
     */
    public static Date parseDate(String dateStr) {
        return parseDate(dateStr, "yyyy-MM-dd");
    }

    /**
     * 功能描述：格式化日期
     *
     * @param dateStr String 字符型日期：YYYY-MM-DD 格式
     * @return Date
     */
    public static Date parseDateTime(String dateStr) {
        return parseDate(dateStr, FULL_DATE_TIME_FORMATE);
    }

    /**
     * 功能描述：格式化日期
     *
     * @param dateStr String 字符型日期：YYYY-MM-DD 格式
     * @return Date
     */
    public static Date parseDateHms(String dateStr) {
        return parseDate(dateStr, "yyyy-MM-dd HH:mm:ss");
    }


    /**
     * 功能描述：格式化输出日期
     *
     * @param date   Date 日期
     * @param format String 格式
     * @return 字符型日期
     */
    public static String format(Date date, String format) {
        String result = "";
        try {
            if (date != null) {
                DateFormat df_format = new SimpleDateFormat(format);
                result = df_format.format(date);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 功能描述：格式化输出日期
     *
     * @param time   时间毫秒
     * @param format String 格式
     * @return 字符型日期
     */
    public static String format(long time, String format) {
        return format(new Date(time), format);
    }


    /**
     * 功能描述：返回字符型日期
     *
     * @param date 日期
     * @return 返回字符型日期 yyyy/MM/dd 格式
     */
    public static String getDate(Date date) {
        return format(date, "yyyy/MM/dd");
    }

    /**
     * 功能描述：返回字符型时间
     *
     * @param date Date 日期
     * @return 返回字符型时间 HH:mm:ss 格式
     */
    public static String getTime(Date date) {
        return format(date, "HH:mm:ss");
    }

    /**
     * 功能描述：返回字符型日期时间
     *
     * @param date Date 日期
     * @return 返回字符型日期时间 yyyy/MM/dd HH:mm:ss 格式
     */
    public static String getDateTime(Date date) {
        return format(date, "yyyy/MM/dd HH:mm:ss");
    }

    public static String getMillisDateTime(Date date) {
        return format(date, "yyyy/MM/dd HH:mm:ss.SSS");
    }


    /**
     * 功能描述：取得指定月份的第一天
     *
     * @param strdate String 字符型日期
     * @return String yyyy-MM-dd 格式
     */
    public static String getMonthBegin(String strdate) {
        Date date = parseDate(strdate);
        return format(date, "yyyy-MM") + "-01";
    }


    /**
     * 功能描述：常用的格式化日期
     *
     * @param date Date 日期
     * @return String 日期字符串 yyyy-MM-dd格式
     */
    public static String formatDate(Date date) {
        return formatDateByFormat(date, "yyyy-MM-dd");
    }

    /**
     * 返回完整格式的日期
     *
     * @param date
     * @return
     * @author linhx
     */
    public static String formateTime(Date date) {
        DateFormat sdf = new SimpleDateFormat(FULL_DATE_TIME_FORMATE);
        return sdf.format(date);
    }

    /**
     * 功能描述：以指定的格式来格式化日期
     *
     * @param date   Date 日期
     * @param format String 格式
     * @return String 日期字符串
     */
    public static String formatDateByFormat(Date date, String format) {
        String result = "";
        if (date != null) {
            try {
                SimpleDateFormat sdf = new SimpleDateFormat(format);
                result = sdf.format(date);
            } catch (Exception ex) {
            }
        }
        return result;
    }

    /**
     * 判断两个时间相隔多少小时
     *
     * @param startTime
     * @param endTime
     * @return
     */
    public static long getHourBetween(Date startTime, Date endTime) {
        SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String start = sd.format(startTime);
        String end = sd.format(endTime);
        long nd = 1000L * 24 * 60 * 60;//一天的毫秒数
        long nh = 1000L * 60 * 60;//一小时的毫秒数
        long nm = 1000L * 60;//一分钟的毫秒数
        long ns = 1000L;//一秒钟的毫秒数
        long diff;
        //获得两个时间的毫秒时间差异
        try {
            diff = sd.parse(end).getTime() - sd.parse(start).getTime();
            long day = diff / nd;//计算差多少天
            long hour = diff % nd / nh;//计算差多少小时
            long min = diff % nd % nh / nm;//计算差多少分钟
            long sec = diff % nd % nh % nm / ns;//计算差多少秒//输出结果
            //System.out.println("时间相差："+day+"天"+hour+"小时"+min+"分钟"+sec+"秒。");
            return hour;
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return 0;
    }

    /**
     * 判断两个时间相隔多少小时
     *
     * @param startTime
     * @param endTime
     * @return
     */
    public static String getHourBetweenString(Date startTime, Date endTime) {
        SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String start = sd.format(startTime);
        String end = sd.format(endTime);
        long nd = 1000 * 24 * 60 * 60;//一天的毫秒数
        long nh = 1000 * 60 * 60;//一小时的毫秒数
        long nm = 1000 * 60;//一分钟的毫秒数
        long ns = 1000;//一秒钟的毫秒数
        long diff;
        //获得两个时间的毫秒时间差异
        try {
            diff = sd.parse(end).getTime() - sd.parse(start).getTime();
            long day = diff / nd;//计算差多少天
            long hour = diff % nd / nh;//计算差多少小时
            long min = diff % nd % nh / nm;//计算差多少分钟
            long sec = diff % nd % nh % nm / ns;//计算差多少秒//输出结果
            //System.out.println("时间相差："+day+"天"+hour+"小时"+min+"分钟"+sec+"秒。");
            return hour + "-" + min + "-" + sec;
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * long类型时间转Date类型(如：20160712172437)
     *
     * @param str
     * @return
     * @throws ParseException
     */
    public static Date getLongParseStringDate(String str) throws ParseException {
        String y, m, d, HH, mm, ss, datetime;
        StringBuffer sb = new StringBuffer();
        y = str.substring(0, 4);
        m = str.substring(4, 6);
        d = str.substring(6, 8);
        HH = str.substring(8, 10);
        mm = str.substring(10, 12);
        ss = str.substring(12, 14);
        sb.append(y).append("-").append(m).append("-").append(d).append(" ").append(HH).append(":").append(mm).append(":").append(ss);
        datetime = sb.toString();
        Date date = parseDateHms(datetime);
        return date;
    }

    public static String unitFormat(int i) {
        String retStr = null;
        if (i >= 0 && i < 10)
            retStr = "0" + Integer.toString(i);
        else
            retStr = "" + i;
        return retStr;
    }

    /**
     * 秒转成时间格式 如15秒=(00:00:15)
     *
     * @param time
     * @return
     */
    public static String secToTime(int time) {
        String timeStr = null;
        int hour = 0;
        int minute = 0;
        int second = 0;
        if (time <= 0)
            return "00:00:00";
        else {
            minute = time / 60;
            if (minute < 60) {
                second = time % 60;
                timeStr = "00:" + unitFormat(minute) + ":" + unitFormat(second);
            } else {
                hour = minute / 60;
                if (hour > 99)
                    return "99:59:59";
                minute = minute % 60;
                second = time - hour * 3600 - minute * 60;
                timeStr = unitFormat(hour) + ":" + unitFormat(minute) + ":" + unitFormat(second);
            }
        }
        return timeStr;
    }

    /**
     * @param second
     * @return
     * @Description: 转换会话时间格式
     * @Author: linhx
     * @Date: 9:04 2017/10/12
     */
    public static String parseSeconds(long second) {
        StringBuilder sb = new StringBuilder();
        long m = second / 60;
        long s = second % 60;
        if (m < 10)
            sb.append("0");
        sb.append(m).append("'");
        if (s < 10)
            sb.append("0");
        sb.append(s).append("''");
        return sb.toString();
    }

    public static Date long2Date(long date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTimeInMillis(date);
        return calendar.getTime();
    }

    /**
     * 根据传入参数获取今天前后的日期, 如0 -今天， -1昨天  1- 明天
     *
     * @param num
     * @return
     */
    public static String getSomeDay(int num, String format) {
        Date date = doCalculateDate(num, format);
        SimpleDateFormat formatter = new SimpleDateFormat(format);
        return formatter.format(date);
    }

    /**
     * 根据传入参数获取今天前后的日期, 如0 -今天， -1昨天  1- 明天
     *
     * @param num
     * @return
     */
    public static Date doCalculateDate(int num, String format) {
        Date date = new Date();
        Calendar calendar = new GregorianCalendar();
        calendar.setTime(date);
        calendar.add(calendar.DATE, num);
        date = calendar.getTime();
        return date;
    }

    public static String Long2Time(String value) {
        String formateTime = "";
        if (StringUtils.isBlank(value))
            formateTime = "00:00:00";
        else if ("0".equals(value))
            formateTime = "00:00:00";
        else {
            String vv = "" + value;
            long time = Long.valueOf(vv);
            if (time == 86399L)
                time += 1L;
            int hour = (int) (time / (60 * 60));
            int minute = (int) (time - hour * 60 * 60) / 60;
            int second = (int) time - hour * (60 * 60) - minute * 60;
            if (hour == 0 && minute == 0 && second == 0)
                formateTime += 0;
            else {
                if (hour > 0) {
                    if (hour < 10)
                        formateTime += "0" + hour;
                    else
                        formateTime += hour;
                } else
                    formateTime += "00";
                if (minute > 0) {
                    if (minute < 10)
                        formateTime += ":0" + minute;
                    else
                        formateTime += ":" + minute;
                } else
                    formateTime += ":00";
                if (second > 0) {
                    if (second < 10)
                        formateTime += ":0" + second;
                    else
                        formateTime += ":" + second;
                } else {
                    formateTime += ":00";
                }
            }
        }
        return formateTime;
    }

    /**
     * @param pattern
     * @return
     * @Description 获取当前日期
     * @author linhx
     * @since 2016-11-11 下午4:37:42
     */
    public static String getCurrentDate(String pattern) {
        String date = null;
        try {
            SimpleDateFormat df = new SimpleDateFormat(pattern);
            date = df.format(new Date());
        } catch (Exception e) {
            LOGGER.error(e.getMessage(), e);
        }
        return date;
    }

    public static Date long2Date(Long time) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTimeInMillis(time);

        return calendar.getTime();
    }

    public static Long date2Long(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);

        return calendar.getTimeInMillis();
    }

    /**
     * 转换时间(超过一小时转为HH:mm:ss，小于一小时转为mm:ss)
     *
     * @param time 毫秒数
     * @return
     */
    public static String parseTime(long time) {
        return parseTime(time, null);
    }

    /**
     * 转换时间(超过一小时转为HH:mm:ss，小于一小时转为mm:ss)
     *
     * @param time      毫秒数
     * @param cutSymbol 时分秒分隔符，默认 :
     * @return
     */
    public static String parseTime(long time, String cutSymbol) {
        if (cutSymbol == null) {
            cutSymbol = ":";
        }
        StringBuilder timeStr = new StringBuilder();
        if (time >= 3600000L) { // 超过一小时
            long hour = time / 3600000L;
            if (hour >= 10) {
                timeStr.append(hour).append(cutSymbol);
            } else {
                timeStr.append("0").append(hour).append(cutSymbol);
            }
            time %= 3600000L;
        }
        long minute = time / 60000L;
        if (minute >= 10) {
            timeStr.append(minute).append(cutSymbol);
        } else {
            timeStr.append("0").append(minute).append(cutSymbol);
        }
        time %= 60000L;
        long second = time / 1000L;
        if (second >= 10) {
            timeStr.append(second);
        } else {
            timeStr.append("0").append(second);
        }
        return timeStr.toString();
    }

    /**
     * 计算2个日期之间的相隔天数
     *
     * @param d1 日期1
     * @param d2 日期2
     * @return 日期1和日期2相隔天数
     */
    public int getDaysBetween(Calendar d1, Calendar d2) {
        if (d1.after(d2)) {
            // swap dates so that d1 is start and d2 is end
            Calendar swap = d1;
            d1 = d2;
            d2 = swap;
        }
        int days = d2.get(Calendar.DAY_OF_YEAR)
                - d1.get(Calendar.DAY_OF_YEAR);
        int y2 = d2.get(Calendar.YEAR);
        if (d1.get(Calendar.YEAR) != y2) {
            d1 = (Calendar) d1.clone();
            do {
                days += d1.getActualMaximum(Calendar.DAY_OF_YEAR);
                d1.add(Calendar.YEAR, 1);
            }
            while (d1.get(Calendar.YEAR) != y2);
        }
        return days;
    }

    /**
     * 计算2个日期之间的工作天数（去除周六周日）
     *
     * @param d1 日期1
     * @param d2 日期2
     * @return 日期1和日期2之间的工作天数
     */
    public int getWorkingDay(Calendar d1, Calendar d2) {
        int result = -1;
        if (d1.after(d2)) {
            // swap dates so that d1 is start and d2 is end
            Calendar swap = d1;
            d1 = d2;
            d2 = swap;
        }

        //int betweendays = getDaysBetween(d1, d2);

        //int charge_date = 0;

        // 开始日期的日期偏移量
        int charge_start_date = 0;
        // 结束日期的日期偏移量
        int charge_end_date = 0;

        int stmp;
        int etmp;
        stmp = 7 - d1.get(Calendar.DAY_OF_WEEK);
        etmp = 7 - d2.get(Calendar.DAY_OF_WEEK);

        // 日期不在同一个日期内
        if (stmp != 0 && stmp != 6) {// 开始日期为星期六和星期日时偏移量为0
            charge_start_date = stmp - 1;
        }
        if (etmp != 0 && etmp != 6) {// 结束日期为星期六和星期日时偏移量为0
            charge_end_date = etmp - 1;
        }
        // }
        result = (getDaysBetween(this.getNextMonday(d1), this.getNextMonday(d2)) / 7)
                * 5 + charge_start_date - charge_end_date;
        // System.out.println("charge_start_date>" + charge_start_date);
        // System.out.println("charge_end_date>" + charge_end_date);
        // System.out.println("between day is-->" + betweendays);
        return result;
    }

    /**
     * 获取当前星期
     *
     * @param date      当前日期
     * @param character zh : 标识中文 ， en : 标识英文（默认）
     * @return 当前日期
     */
    public String getChineseWeek(Calendar date, String character) {
        String[] dayNames =
                {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};

        if ("zh".equals(character)) {
            dayNames[0] = "星期日";
            dayNames[1] = "星期一";
            dayNames[2] = "星期二";
            dayNames[3] = "星期三";
            dayNames[4] = "星期四";
            dayNames[5] = "星期五";
            dayNames[6] = "星期六";
        }
        int dayOfWeek = date.get(Calendar.DAY_OF_WEEK);

        // System.out.println(dayNames[dayOfWeek - 1]);
        return dayNames[dayOfWeek - 1];

    }

    /**
     * 获得日期的下一个星期一的日期
     *
     * @param date
     * @return
     */
    public Calendar getNextMonday(Calendar date) {
        Calendar result = null;
        result = date;
        do {
            result = (Calendar) result.clone();
            result.add(Calendar.DATE, 1);
        }
        while (result.get(Calendar.DAY_OF_WEEK) != 2);
        return result;
    }

    /**
     * 计算两个日期之间的非工作日天数
     *
     * @param d1 日期1
     * @param d2 日期2
     * @return 日期1与日期2之间的非工作天数
     */
    public int getHolidays(Calendar d1, Calendar d2) {
        return this.getDaysBetween(d1, d2) - this.getWorkingDay(d1, d2);

    }
}
